package com.lsh.payment.worker.service;

import com.alibaba.fastjson.JSON;
import com.lsh.payment.api.model.basevo.BaseResponse;
import com.lsh.payment.api.model.basevo.ExceptionStatus;
import com.lsh.payment.api.model.refund.RefundResponse;
import com.lsh.payment.core.exception.BusinessException;
import com.lsh.payment.core.handler.IRefundChannelHandler;
import com.lsh.payment.core.model.payasync.EmailModel;
import com.lsh.payment.core.model.payenum.IsValid;
import com.lsh.payment.core.model.payenum.PayChannel;
import com.lsh.payment.core.model.payment.PayDeal;
import com.lsh.payment.core.model.refund.PayRefund;
import com.lsh.payment.core.model.refund.RefundTask;
import com.lsh.payment.core.service.async.PayEventBus;
import com.lsh.payment.core.service.payment.impl.PayDealService;
import com.lsh.payment.core.service.proxy.RefundNotifyProxy;
import com.lsh.payment.core.service.refund.IRefundTaskService;
import com.lsh.payment.core.service.refund.PayRefundOrderService;
import com.lsh.payment.core.service.refund.RefundOrderHandlerService;
import com.lsh.payment.core.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Project Name: lsh-payment
 *
 * @author peter
 * @date 18/6/5
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service
@Slf4j
public class RefundTaskJopService {

    @Autowired
    private IRefundTaskService refundTaskService;

    @Autowired
    private PayRefundOrderService payRefundOrderService;

    @Autowired
    private PayDealService payDealService;

    @Autowired
    private RefundOrderHandlerService refundOrderHandlerService;

    @Autowired
    private RefundNotifyProxy refundNotifyProxy;

    @Value("${to.user.email}")
    private String userEmail;

    /**
     * 获取任务列表
     *
     * @param taskType      任务类型
     * @param times         执行次数
     * @param excludeStatus 过滤状态
     * @return 任务列表
     */
    public List<RefundTask> getRefundTasks(Integer taskType, Integer times, Integer excludeStatus) {

        RefundTask refundTask = new RefundTask();
        refundTask.setStatus(excludeStatus);
        refundTask.setTaskType(taskType);
        refundTask.setIsValid(IsValid.VALID_TRUE.getValue());
        refundTask.setTimes(times);

        return this.getRefundTasks(refundTask);
    }

    /**
     * 获取任务列表
     *
     * @param filter 查询条件
     * @return 返回列表
     */
    private List<RefundTask> getRefundTasks(RefundTask filter) {

        return refundTaskService.selectRefundTask4Task(filter);
    }

    /**
     * 处理退款请求任务
     *
     * @param refundTask 任务信息
     */
    public Boolean dealRefundTaskApply(RefundTask refundTask) {

        String paymentRefundNo = refundTask.getRefId();
        PayRefund payRefund = this.payRefundOrderService.selectRefundByPayRefundNo(paymentRefundNo);
        PayDeal payDeal;
        PayChannel payChannel;
        if(StringUtils.isBlank(payRefund.getPayPaymentNo())){
            payDeal = null;
            payChannel = PayChannel.PURSE_BALANCE_PAY;
        }else{
            payDeal = this.payDealService.queryPayDealByPayPaymentNo(payRefund.getPayPaymentNo());
            payChannel = PayChannel.getPayChannel(payDeal.getPayChannel());
        }

        if (payChannel == null) {
            throw new BusinessException(ExceptionStatus.E2001006.getCode(), "暂不支持该渠道的退款");
        }

        IRefundChannelHandler refundChannelHandler = this.refundOrderHandlerService.getRefundChannelHandler(payChannel);

        if (refundChannelHandler == null) {
            log.info("退款申请渠道异常 payChannel {}", JSON.toJSONString(payChannel));
            return false;
        }

        RefundResponse refundResponse = refundChannelHandler.refund(payRefund, payDeal);
        log.info("退款申请结果 {}", JSON.toJSONString(refundResponse));

        if (refundResponse.getRet() == 0) {
            return true;
        } else {
            StringBuilder emailBuffer = new StringBuilder("【退款流水号】[")
                    .append(paymentRefundNo).append("]\n")
                    .append("申请退款失败,请人工处理...");
            this.sendEmail(emailBuffer);
        }

        return false;
    }

    /**
     * 发送邮件
     * @param emailBuffer  邮件内容
     */
    private void sendEmail(StringBuilder emailBuffer) {

        String[] userEmails = userEmail.split(",");

        log.info("发送邮件地址:" + Arrays.toString(userEmails));

        String title = "支付退款监控_" + DateUtil.defaultDate(new Date());

        //异步邮件发送
        PayEventBus.post(new EmailModel(emailBuffer.toString(), title, userEmails));
    }

    /**
     * 处理退款查询任务
     *
     * @param refundTask 任务信息
     */
    public Boolean dealRefundTaskQuery(RefundTask refundTask) {

        String paymentRefundNo = refundTask.getRefId();

        PayRefund payRefund = this.payRefundOrderService.selectRefundByPayRefundNo(paymentRefundNo);

        PayDeal payDeal;
        PayChannel payChannel;
        if(StringUtils.isBlank(payRefund.getPayPaymentNo())){
            payDeal = null;

            payChannel = PayChannel.PURSE_BALANCE_PAY;
        }else{
            payDeal = this.payDealService.queryPayDealByPayPaymentNo(payRefund.getPayPaymentNo());

            payChannel = PayChannel.getPayChannel(payDeal.getPayChannel());
        }

        if (payChannel == null) {
            throw new BusinessException(ExceptionStatus.E2001006.getCode(), "暂不支持该渠道的退款");
        }

        IRefundChannelHandler refundChannelHandler = this.refundOrderHandlerService.getRefundChannelHandler(payChannel);

        if (refundChannelHandler == null) {

            log.info("退款申请渠道异常 payChannel {}", JSON.toJSONString(payChannel));
            return false;
        }

        BaseResponse baseResponse = refundChannelHandler.refundQuery(payRefund, payDeal);

        log.info("退款查询结果信息 {}", JSON.toJSONString(baseResponse));

        if (baseResponse.getRet() == 0) {
            return true;
        }

        if (baseResponse.getRet().equals(Integer.valueOf(ExceptionStatus.E2000000.getCode()))) {
            if (refundTask.getTimes() > 9) {
                StringBuilder emailBuffer = new StringBuilder("【退款流水号】[").append(paymentRefundNo).append("]\n")
                        .append("查询退款结果(").append(refundTask.getTimes()).append("0)次，退款进行中......");

                this.sendEmail(emailBuffer);
            }
        }

        return false;
    }


    /**
     * 处理退款请求任务
     *
     * @param refundTask 任务信息
     */
    public Boolean dealRefundTaskNotify(RefundTask refundTask) {

        PayRefund payRefund = this.payRefundOrderService.selectRefundByPayRefundNo(refundTask.getRefId());

        if (payRefund == null) {
            return false;
        }

        return refundNotifyProxy.dealRefundNotify(payRefund, refundTask);
    }


}
